import type { AlovaGenerics, AlovaMethodCreateConfig } from 'alova'
import type adapterFetch from 'alova/fetch'
import { createAlova } from 'alova'
import { createClientTokenAuthentication } from 'alova/client'

import VueHook from 'alova/vue'

import mock from './mock'

const { onAuthRequired, onResponseRefreshToken } = createClientTokenAuthentication<
  typeof VueHook,
  typeof adapterFetch
>({
  assignToken: (method) => {
    console.log('method', method)

    // method.config.headers.Authorization = localStorage.getItem('token')
  }
})

export const alova = createAlova({
  statesHook: VueHook,

  baseURL: './',

  // requestAdapter: adapterFetch(),
  requestAdapter: mock,

  beforeRequest: onAuthRequired((_method) => {
    // ...
  }),

  // 使用 responded 对象分别指定请求成功的拦截器和请求失败的拦截器

  responded: onResponseRefreshToken({
    // 请求成功的拦截器
    // 当使用 `alova/fetch` 请求适配器时，第一个参数接收Response对象
    // 第二个参数为当前请求的method实例，你可以用它同步请求前后的配置信息

    onSuccess: async (response) => {
      console.log('responsded', response)

      if (response.ok) {
        const data = await response.json()

        console.log('ok:data', data)

        return data
      } else {
        const error = new Error(response.statusText)
        return Promise.reject(error)
      }
    },

    // 请求失败的拦截器
    // 请求错误时将会进入该拦截器。
    // 第二个参数为当前请求的method实例，你可以用它同步请求前后的配置信息

    onError: (error, _method) => {
      console.log('error', error.message)
    },

    // 请求完成的拦截器
    // 当你需要在请求不论是成功、失败、还是命中缓存都需要执行的逻辑时，可以在创建alova实例时指定全局的`onComplete`拦截器，例如关闭请求 loading 状态。
    // 接收当前请求的method实例

    onComplete: async (_method) => {
      // 处理请求完成逻辑

      console.log('111')
    }
  }),

  // 全局关闭全部请求缓存

  cacheFor: null
})

export function Get<Responded = unknown, Transformed = unknown>(
  url: string,
  config?: AlovaMethodCreateConfig<AlovaGenerics<Responded, Transformed>, Responded, Transformed>
) {
  return alova.Get<Responded, Transformed>(url, config)
}
export const Post = alova.Post
export const Put = alova.Put
export const Delete = alova.Delete
export const Head = alova.Head
export const Options = alova.Options
export const Patch = alova.Patch

export default alova
